package com.youwatch.concurrency.example.count;

import com.youwatch.concurrency.annotations.ThreadSafe;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Author: kss
 * @Description:
 * @Date: Create in 2019/1/15
 */
@Slf4j
@ThreadSafe
public class CountExample2 {

    //请求总数
    public static int clientTotal = 5000;
    //同时并发执行的线程数
    public static int threadTotal = 200;
    //计数的值
    public static AtomicInteger count = new AtomicInteger(0);

    public static void main(String[] args) throws InterruptedException {
        //定义线程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //定义信号量-参数-允许并发的数目
        final Semaphore semaphore = new Semaphore(threadTotal);
        //定义计数器闭锁-所有请求完结束统计结果
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        //放入请求
        for (int i = 0; i < clientTotal; i++) {
            //将所有请求放入线程池中-JDK1.8写作方式
            executorService.execute(() -> {
                try {
                    //引入信号量
                    semaphore.acquire();//是否允许执行，不允许会被阻塞
                    add();
                    semaphore.release();
                } catch (Exception e) {
                    log.error("exception", e);
                }
                //引入闭锁
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();//保证前面所有线程执行完
        executorService.shutdown();//线程池关闭
        log.info("count:{}", count.get());//所有线程执行完打印计数的值
    }

    //计数方法
    private static void add() {
        count.incrementAndGet();// ++i
//        count.getAndIncrement();// i++
    }
}
